package cn.com.cis.web.actions;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributesModelMap;

import cn.com.cis.domain.Role;
import cn.com.cis.plugins.mybatis.PageInfo;
import cn.com.cis.service.PrivilegeService;
import cn.com.cis.service.RoleService;
import cn.com.cis.utils.tree.PermissionArrayManager;
import cn.com.cis.utils.tree.PermissionWithProperties;
import cn.com.cis.web.bean.RoleActionBean;

@Controller
@RequestMapping(value = "/role")
public class RoleController {
	
	@Autowired
	private RoleService roleService;
	
	@Autowired
	private PrivilegeService privilegeService;
	
	private void setNavigateBar(ModelAndView mv){
    	mv.addObject("icon", "icon-list");
        mv.addObject("title", "角色管理");
    }

	@RequiresPermissions("配置管理:角色管理:查看角色列表")
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public ModelAndView login(@RequestParam(value = "page", defaultValue = "1", required = false) int page,
            @RequestParam(value = "pageSize", defaultValue = "5", required = false) int pageSize, HttpServletRequest request) {
		ModelAndView mv = new ModelAndView("role/list");
		setNavigateBar(mv);
		
		List<Role> roles = roleService.selectRoles(page, pageSize);
		PageInfo<Role> pageInfo = new PageInfo<Role>(roles, pageSize);
		
		mv.addObject("page",page);
		mv.addObject("roles", roles);
        mv.addObject("pageInfo", pageInfo);
        
        mv.addObject("msg", request.getParameter("msg"));
        mv.addObject("error", request.getParameter("error"));

		return mv;
	}
	
	@RequiresPermissions("配置管理:角色管理:修改角色")
    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public ModelAndView editView(Integer roleId) {
        ModelAndView mav = new ModelAndView("role/edit");
        setNavigateBar(mav);
        
        Role role = roleService.selectRoleByRoleId(roleId);
        
        PermissionArrayManager pam = new PermissionArrayManager();
        pam.setPrivilegeService(privilegeService);
        pam.setRoleService(roleService);
        pam.isSetPermissionsForRole(true);
        pam.setRole(roleService.selectRoleByRoleId(roleId));
		
		Map<String, List<PermissionWithProperties>> permissionArray = pam.getPermissionArray();

		mav.addObject("role", role);
		mav.addObject("permissionArray", permissionArray);
		
        return mav;
    }
	
	@RequiresPermissions("配置管理:角色管理:修改角色")
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
	@ResponseBody
    public String edit(RoleActionBean rolebean) throws UnsupportedEncodingException {
		
		// 动作合法性验证
		Role roleValid = roleService.selectRoleByRoleId(rolebean.getRoleId());
		if("admin".equals(roleValid.getRoleName())){
			return "admin角色不允许被修改！";
		}
		// 动作合法性验证
		
		// 用户输入校验
		if (null == rolebean.getRoleName() || !rolebean.getRoleName().matches("[a-zA-Z]{2,}")) {
			return "角色名不合法！";
		}

		if (null != roleService.selectRoleByRoleName(rolebean.getRoleName())) {
			String oldRoleName = roleService.selectRoleByRoleName(rolebean.getRoleName()).getRoleName();
			if(!rolebean.getRoleName().equals(oldRoleName)){
				return "角色名已存在！";
			}
		}

		if (null == rolebean.getDes() || rolebean.getDes().trim().length() == 0) {
			return "对角色的描述不能为空";
		}
		// 用户输入校验
		
        Role role = new Role();
        role.setRoleName(rolebean.getRoleName());
        role.setDes(rolebean.getDes());
        role.setRoleId(rolebean.getRoleId());
        
        try {
			editRole(role, rolebean.getPermissions());
		} catch (Exception e) {
			e.printStackTrace();
			return e.getMessage();
		}
        
        return "success";
    }
	
	// TODO should be in one transaction
	private void editRole(Role role, String permissions) throws UnsupportedEncodingException{
        roleService.updateRole(role);
        
        roleService.clearPermissions(role.getRoleId());
        for(String permissionString : URLDecoder.decode(permissions, "UTF-8").split(";")){
        	if(!"".equals(permissionString)){
        		roleService.addPermissionForRole(role.getRoleId(), permissionString);
        	}
        }
	}
	
	// TODO message or error cannot be show on page
	@RequiresPermissions("配置管理:角色管理:删除角色")
    @RequestMapping(value = "/delete", method = RequestMethod.GET)
    public ModelAndView del(int id, int page, RedirectAttributesModelMap modelMap) throws UnsupportedEncodingException {
		ModelAndView mv = new ModelAndView("redirect:/role/list?page=" + page);
		setNavigateBar(mv);
		
		// 动作合法性验证
		Role roleValid = roleService.selectRoleByRoleId(id);
		if ("admin".equals(roleValid.getRoleName())) {
			mv.setViewName("redirect:/role/list?page=" + page + "&error=" + URLEncoder.encode("不允许删除admin用户！", "UTF-8"));
			return mv;
		}
		// 动作合法性验证
		
		try {
			roleService.deleteRoleById(id);
		} catch (Exception e) {
			e.printStackTrace();
			mv.setViewName("redirect:/role/list?page=" + page + "&error=" + URLEncoder.encode(e.getMessage(), "UTF-8"));
			return mv;
		}
		
		mv.setViewName("redirect:/role/list?page=" + page + "&msg=" + URLEncoder.encode("删除成功！", "UTF-8"));
        return mv;
    }
	
	@RequiresPermissions("配置管理:角色管理:添加角色")
    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public ModelAndView addView() {
        ModelAndView mav = new ModelAndView("role/add");
        setNavigateBar(mav);
        
        PermissionArrayManager pam = new PermissionArrayManager();
        pam.setPrivilegeService(privilegeService);
        
        Map<String, List<PermissionWithProperties>> permissionArray = pam.getBlankPermissionArray();
        
		mav.addObject("permissionArray", permissionArray);
		
        return mav;
    }
	
	@RequiresPermissions("配置管理:角色管理:添加角色")
    @RequestMapping(value = "/add", method = RequestMethod.POST)
	@ResponseBody
    public String add(RoleActionBean rolebean) throws UnsupportedEncodingException {
		
		// 用户输入校验
		if(!rolebean.getRoleName().matches("[a-zA-Z]{2,}")){
			return "角色名不合法！";
		}
		
		if(null != roleService.selectRoleByRoleName(rolebean.getRoleName())){
			return "角色名已存在！";
		}
		
		if(null == rolebean.getDes() || rolebean.getDes().trim().length() == 0){
			return "对角色的描述不能为空";
		}
		// 用户输入校验
		
		Role role = new Role();
        role.setRoleName(rolebean.getRoleName());
        role.setDes(rolebean.getDes());
        
        try {
			addRole(role, rolebean.getPermissions());
		} catch (Exception e) {
			e.printStackTrace();
			return e.getMessage();
		}
		
        return "success";
    }
	
	// TODO should be in one transaction
	private void addRole(Role role, String permission) throws UnsupportedEncodingException {
		roleService.insertRole(role);

		for (String permissionString : URLDecoder.decode(permission, "UTF-8").split(";")) {
			if (!"".equals(permissionString)) {
				roleService.addPermissionForRole(role.getRoleId(), permissionString);
			}
		}
	}

}
